Skip to content

Ship the licenses the downloads only named - #557

Merged
thcp merged 2 commits into
mainfrom
fix/license-notices
Sep 1, 2026
Merged

Ship the licenses the downloads only named#557
thcp merged 2 commits into
mainfrom
fix/license-notices

Conversation

@thcp

@thcp thcp commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Closes #555

The problem

THIRD_PARTY_NOTICES.txt named a dependency and its license:

Demucs
License: MIT

MIT, BSD and Apache-2.0 all ask for more than that. The copyright notice and the license text itself have to accompany a binary distribution. A name and an SPDX identifier is an inventory, not a notice.

The file said so about itself, in its own third paragraph, and had been saying it for every release since it was written.

Generated, not maintained

scripts/collect_licenses.py reads the packaged venv's .dist-info and writes licenses/ into the download: one file per dependency carrying its real license text, plus an INDEX.txt listing name, version and license.

It runs after the strip, so it describes what actually ships rather than what was installed.

Generated rather than hand-written because three lists across three platforms drift the first time a dependency changes and nothing reads them. Windows listed 74 lines, Linux 78, macOS 20, against a venv holding 107 packages.

Two details that matter:

  • A wheel shipping no license file is recorded, not fatal. Five of the 107 genuinely have none, and failing a release build over that would be worse than writing it down.
  • Apache-2.0 dependencies carrying their own NOTICE get it passed through. Torch has one.

Stdlib only, because it runs against the bundled interpreter partway through packaging, before anything exists that is not a runtime dependency.

FFmpeg source offer

FFmpeg is a GPL build on all three platforms, from a different builder on each: BtbN on Windows, johnvansickle on Linux, evermeet on macOS.

It is downloaded and run as a separate executable, never linked, so it does not reach StemDeck's own Apache-2.0 license. But distributing a GPL binary carries an obligation to make the corresponding source available, and nothing did. Each platform's notice now names its exact build and where that build's source lives.

README

A short ## License section. That one is courtesy rather than compliance: the obligation travels with the binary, not with the repository.

Verification

Packaged Windows end to end from this branch rather than trusting the wiring, since an untested change to a release packager is exactly what #517 was about:

licenses: 107 packages, 102 with license text
licenses: no text bundled for 5: Cython, antlr4-python3-runtime, flatbuffers, onnxruntime, samplerate
Variant     : CPU-only
Zip created : dist\StemDeck-Windows-x64.zip

licenses/ is present in the staged package with 134 files, INDEX.txt among them.

bash -n   make-portable.sh, make-runtime-pack.sh   clean
ps parse  make-portable.ps1                        clean
ruff check / ruff format --check                   clean

Linux and macOS packaging are wired the same way but only syntax-checked here. Neither packager runs on this machine.

Not a legal opinion

I am not a lawyer. This closes the two obligations that looked plainly unmet: license texts travelling with the binary, and a source offer for the GPL component.

Thales added 2 commits September 1, 2026 13:50
Unraid users pull exactly the tag in <Repository>, so a template left on
0.16.0 means a Community Applications install gets 0.16.0 and an existing
one is never offered anything newer. 0.16.1 is published and promoted and
its image is on GHCR, so the tag it points at exists.

The pin is bumped after the image is pushed rather than at merge time. A
template pointing at a tag that has not been published yet is worse than
one a release behind: the first fails to pull, the second at least runs.
THIRD_PARTY_NOTICES.txt listed a dependency and the name of its license.
MIT, BSD and Apache-2.0 all ask for more: the copyright notice and the
license text itself have to accompany a binary. The file said so about
itself, calling itself a starter notice and not a substitute for the
inventory that must be generated from the packaged runtime. It has been
saying that for every release since.

collect_licenses.py generates that inventory from the venv rather than
from anyone's memory. It runs after the strip, so it describes what
actually ships, and writes licenses/ with each package's own license text
plus an INDEX.txt naming version and license. Stdlib only, because it runs
against the bundled interpreter partway through packaging, before anything
that is not a runtime dependency exists.

A wheel that ships no license file is recorded, not fatal. Five of the 107
genuinely have none, and failing a release build over that would be worse
than writing it down. Apache-2.0 dependencies carrying their own NOTICE
get it passed through; torch has one.

Generated rather than maintained because three hand-written lists across
three platforms drift the first time a dependency changes, and nothing
reads them. Windows listed 74 lines, Linux 78 and macOS 20 against a venv
of 107 packages.

FFmpeg is a GPL build on all three platforms, from a different builder on
each. It is downloaded and run as a separate executable, never linked, so
it does not reach StemDeck's own license, but distributing it carries an
obligation to make the corresponding source available and nothing did.
Each platform's notice now names its build and where that build's source
is.

The README gains a short License section. That is courtesy rather than
compliance: the obligation travels with the binary, not the repository.

Verified by packaging Windows end to end: 107 packages, 102 with license
text, licenses/ present in the staged package with 134 files.
@thcp
thcp merged commit 1c4ec3b into main Sep 1, 2026
10 checks passed
@thcp
thcp deleted the fix/license-notices branch September 3, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Downloads name their dependencies' licenses without shipping them

1 participant